package com.example.pay.util;

import java.security.SecureRandom;

/**
 * 构造微信支付V3 API的Authorization头（WECHATPAY2-SHA256-RSA2048）。
 */
public class WeChatV3AuthUtil {

    public static class AuthHeader {
        public final String header;
        public final String timestamp;
        public final String nonce;
        public AuthHeader(String header, String timestamp, String nonce) {
            this.header = header;
            this.timestamp = timestamp;
            this.nonce = nonce;
        }
    }

    /**
     * 构造Authorization头。
     * @param method HTTP方法，如"POST"
     * @param canonicalUrl 请求路径及查询串，如"/v3/pay/transactions/app"
     * @param body 请求体JSON字符串
     * @param mchId 商户号
     * @param serialNo 商户证书序列号
     * @param merchantPrivateKey 商户私钥（PEM）
     */
    public static AuthHeader buildAuth(String method,
                                       String canonicalUrl,
                                       String body,
                                       String mchId,
                                       String serialNo,
                                       String merchantPrivateKey) {
        String timestamp = String.valueOf(System.currentTimeMillis() / 1000);
        String nonceStr = randomNonce();
        String message = method + "\n" + canonicalUrl + "\n" + timestamp + "\n" + nonceStr + "\n" + (body == null ? "" : body) + "\n";

        String signature = RsaSignUtil.signSHA256withRSA(message, merchantPrivateKey);
        String auth = String.format("WECHATPAY2-SHA256-RSA2048 mchid=\"%s\",nonce_str=\"%s\",timestamp=\"%s\",serial_no=\"%s\",signature=\"%s\"",
                mchId, nonceStr, timestamp, serialNo, signature);
        return new AuthHeader(auth, timestamp, nonceStr);
    }

    private static String randomNonce() {
        byte[] bytes = new byte[16];
        new SecureRandom().nextBytes(bytes);
        StringBuilder sb = new StringBuilder();
        for (byte b : bytes) {
            String s = Integer.toHexString(b & 0xff);
            if (s.length() == 1) sb.append('0');
            sb.append(s);
        }
        return sb.toString();
    }
}